home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / terms / tipx / slip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-02  |  5.4 KB  |  245 lines

  1. #ifndef lint
  2. static char *sccsid = "%W%    MS/ACF    %E%";
  3. #endif
  4. #ifdef SUNOS41 /* wht@n4hgf2 */
  5. #include <stdio.h>
  6. runslip()
  7. {
  8.     fprintf(stderr,"Sorry, not working in this OS\n");
  9.     return(1);
  10. }
  11. abort_slip()
  12. {
  13. }
  14. #else /* wht@n4hgf2 */
  15. /*
  16.  *  tip/slip.c
  17.  *
  18.  *  This file contains the SLIP specific startup code.  It is designed
  19.  *  with both BSD sockets and Sun Streams in mind, though the socket
  20.  *  version has not been tested lately (but it SHOULD work).  The Streams
  21.  *  code is for SunOS 4.0[.1].
  22.  *
  23.  *  The code to set the route (basically an internal shell script) may
  24.  *  need tweeking on other systems, though it works on any of the
  25.  *  systems I have run into.
  26.  *
  27.  *  The alarm/DCD code is a HACK to detect loss of the line in the
  28.  *  absense of proper modems status signaling (broken in SunOS when
  29.  *  using the dialout device, serial line minor devices 128-255).
  30.  *  This has been reported, but I suspect that a fix will have to
  31.  *  wait for SunOS 4.2 or maybe 4.1.?.
  32.  *
  33.  *  Doug Kingston <dpk@morgan.com>
  34.  *  880219
  35.  */
  36.  
  37. #include "tip.h"
  38.  
  39. #include <sys/socket.h>
  40. #ifdef STREAMS
  41. #include <sys/stropts.h>
  42. #include <sys/sockio.h>
  43. #include <sys/termios.h>    /* has defines that clash with ioctl.h */
  44. #include <sys/slip.h>
  45. #endif STREAMS
  46. #include <netinet/in.h>
  47. #include <net/if.h>
  48.  
  49. #include <arpa/inet.h>
  50.  
  51. #define    DCD_SETTLING_TIME 1    /* time between DCD change and status check */
  52. #define    DCD_CHECK_INTERVAL 15    /* if > 0, time between automatic DCD checks */
  53.  
  54. int gotsig = 0;
  55. sigfunc_t dcd_handler();
  56.  
  57. runslip()
  58. {
  59.     int unit, s;
  60.     struct ifreq ifr;
  61. #ifdef STREAMS /* Using streams */
  62.     struct termios tios;
  63.  
  64.     /* pop all streams modules */
  65.     while (ioctl(FD, I_POP, 0) == 0)
  66.         continue;
  67.  
  68.     /* set up the line parameters */
  69.     if (ioctl(FD, TCGETS, (caddr_t)&tios) < 0) {
  70.         perror("ioctl (TCGETS)");
  71.         return(1);
  72.     }
  73.     tios.c_cflag = (tios.c_cflag&(CBAUD|CIBAUD))|CS8|CREAD|HUPCL;
  74.     tios.c_iflag = IGNBRK;
  75.     if (ioctl(FD, TCSETS, (caddr_t)&tios) < 0) {
  76.         perror("ioctl (TCSETS)");
  77.         return(1);
  78.     }
  79.  
  80.     /* push the SLIP module */
  81.     if (ioctl(FD, I_PUSH, "slip") < 0) {
  82.         perror("ioctl (I_PUSH)");
  83.         return(1);
  84.     }
  85.  
  86.     /* find out what unit number we were assigned */
  87.     if (ioctl(FD, SLIOGUNIT, (caddr_t)&unit) < 0) {
  88.         perror("ioctl (SLIOGUNIT)");
  89.         return(1);
  90.     }
  91. #else /* not streams */
  92.     int ldisc = SLIPDISC;
  93.     if (ioctl(FD, TIOCSETD, &ldisc) < 0) {
  94.         perror("slipd: TIOCSETD");
  95.         return(1);
  96.     }
  97.     if (ioctl(FD, TIOCGETD, &unit) < 0) {    /* Hack to get slip number */
  98.         perror("slipd: TIOCGETD");
  99.         return(1);
  100.     }
  101. #endif I_POP
  102.  
  103.     /* set the local and remote interface addresses */
  104.     s = socket(AF_INET, SOCK_DGRAM, 0);
  105.  
  106.     (void) sprintf(ifr.ifr_name, "slip%d", unit);
  107.     if (in_getaddr(DA, &ifr.ifr_addr) != 0 ||
  108.         ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
  109.         perror("ioctl (SIOCSIFDSTADDR)");
  110.         return(1);
  111.     }
  112.  
  113.     /* this has the side-effect of marking the interface up */
  114.     if (in_getaddr(SA, &ifr.ifr_addr) != 0 ||
  115.         ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
  116.         perror("ioctl (SIOCSIFADDR)");
  117.         return(1);
  118.     }
  119.  
  120.     if (in_getaddr(SM, &ifr.ifr_addr) != 0) {
  121.         if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
  122.             perror("ioctl (SIOCSIFADDR)");
  123.             return(1);
  124.         }
  125.     }
  126.  
  127.     /* Set up default route if desired and not already present */
  128.     if (boolean(value(SETROUTE))) {
  129.         char buf[256];
  130.         char *argv[4];
  131.         char *envp[2];
  132.         int status;
  133.  
  134.         sprintf(buf, "if eval 'netstat -r|grep -s \"^default\"';\
  135.                   then echo default route already installed;\
  136.                   else route add 0 %s 3; fi", SA);
  137.         argv[0] = "/bin/sh";
  138.         argv[1] = "-c";
  139.         argv[2] = buf;
  140.         argv[3] = (char *)0;
  141.  
  142.         envp[0] = "PATH=/bin:/usr/bin:/usr/ucb:/etc:/usr/etc";
  143.         envp[1] = (char *)0;
  144.  
  145.         switch (fork()) {
  146.         case 0:        /* Child */
  147.             execve(argv[0], argv, envp);
  148.             exit(1);
  149.         case -1:
  150.             perror("tip: route add: fork");
  151.             break;
  152.         default:    /* Parent */
  153.             wait(&status);
  154.         }
  155.     }
  156.  
  157.     fprintf(stderr, "\07[SLIP running]\r\n");
  158.  
  159.     /* set up signal handlers */
  160.     (void) sigblock(sigmask(SIGALRM));
  161.     (void) signal(SIGALRM, dcd_handler);
  162. #if defined(SIGDCD) && SIGDCD > 0
  163.     (void) signal(SIGDCD, dcd_handler);
  164. #endif
  165.  
  166.     /* twiddle thumbs until we get a signal */
  167.     while (1) {
  168.         alarm(DCD_CHECK_INTERVAL);
  169.         sigpause(0);
  170. #if defined(SIGDCD) && SIGDCD > 0
  171.         (void) sigblock(sigmask(SIGALRM)|sigmask(SIGDCD));
  172. #else
  173.         (void) sigblock(sigmask(SIGALRM));
  174. #endif SIGDCD
  175.         if (gotsig && lowdcd(FD)) {
  176.             sleep(DCD_SETTLING_TIME);
  177.             if (lowdcd(FD))
  178.                 break;
  179.         }
  180.         gotsig = 0;
  181.     }
  182.     return(0);
  183. }
  184.  
  185. abort_slip()
  186. {
  187. #ifdef STREAMS
  188.     /* pop the SLIP stream module */
  189.     while(ioctl(FD, I_POP, 0) == 0);
  190. #else
  191.     int ldisc = 0;
  192.     (void)ioctl(FD, TIOCSETD, &ldisc);
  193. #endif
  194. }
  195.  
  196. sigfunc_t
  197. dcd_handler()
  198. {
  199.     gotsig = 1;
  200. }
  201.  
  202. /* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
  203. int
  204. lowdcd(fd)
  205.     int fd;
  206. {
  207.     int mbits;
  208.  
  209.     if (ioctl(fd, TIOCMGET, (caddr_t)&mbits) < 0)
  210.         return 1;    /* port is dead, we die */
  211.     return !(mbits & TIOCM_CAR);
  212. }
  213.  
  214. in_getaddr(s, saddr)
  215.     char *s;
  216.     struct sockaddr *saddr;
  217. {
  218.     register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
  219.     struct hostent *hp;
  220.     struct netent *np;
  221.     int val;
  222.  
  223.     sin->sin_family = AF_INET;
  224.     val = inet_addr(s);
  225.     if (val != -1) {
  226.         sin->sin_addr.s_addr = val;
  227.         return(0);
  228.     }
  229.     hp = gethostbyname(s);
  230.     if (hp) {
  231.         sin->sin_family = hp->h_addrtype;
  232.         bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
  233.         return(0);
  234.     }
  235.     np = getnetbyname(s);
  236.     if (np) {
  237.         sin->sin_family = np->n_addrtype;
  238.         sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
  239.         return(0);
  240.     }
  241.     fprintf(stderr, "tip: in_getaddr: can't parse/lookup '%s'\n", s);
  242.     return(1);
  243. }
  244. #endif /* wht@n4hgf2 */
  245.